package com.thankgod7.jobcenter.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thankgod7.jobcenter.constant.Constants;
import com.thankgod7.jobcenter.entity.JobDataPushLog;
import com.thankgod7.jobcenter.mapper.JobDataPushMapper;
import com.thankgod7.jobcenter.service.IJobDataPushLogService;
import com.thankgod7.jobcenter.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * JobDataPushServiceImpl
 *
 * @author thankgod7
 */
@Service
public class JobDataPushServiceImpl extends ServiceImpl<JobDataPushMapper, JobDataPushLog> implements IJobDataPushLogService {

    private static final String RTN_MSG_FIELD = "message";

    private static final String RTN_CODE_FIELD = "success";

    @Resource
    RedisUtil redisUtil;

    @Override
    @Async("DataPushExecutor")
    @Transactional(rollbackFor = Throwable.class)
    public void push(String cacheKey, Integer cacheVal, Long cacheSeconds, String pushUrls, String dataType, String dataJson) {
        List<JobDataPushLog> jobDataPushLogList = new ArrayList<>();
        if (StringUtils.isNotBlank(pushUrls)) {
            for (String pushUrl : pushUrls.split(Constants.DATA_PUSH_URL_MULTIPLE_SPLIT)) {
                JobDataPushLog log = new JobDataPushLog();
                log.setDataType(dataType);
                log.setJobData(dataJson);
                log.setPushUrl(pushUrl);
                try {
                    String respStr = HttpUtil.post(pushUrl, dataJson);
                    JSONObject respObj = JSONObject.parseObject(respStr);
                    if (respObj.getBoolean(RTN_CODE_FIELD)) {
                        log.setStatus(Constants.DATA_PUSH_STATUS_SUCCESS);
                        redisUtil.set(cacheKey, cacheVal, cacheSeconds, TimeUnit.SECONDS);
                    } else {
                        log.setStatus(Constants.DATA_PUSH_STATUS_FAIL);
                        log.setRemark(respObj.getString(RTN_MSG_FIELD));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.setStatus(Constants.DATA_PUSH_STATUS_FAIL);
                    log.setRemark(e.getMessage());
                }
                jobDataPushLogList.add(log);
            }
        } else {
            JobDataPushLog log = new JobDataPushLog();
            log.setStatus(Constants.DATA_PUSH_STATUS_PENDING);
            log.setJobData(dataJson);
            log.setDataType(dataType);
            jobDataPushLogList.add(log);
        }
        this.saveBatch(jobDataPushLogList);
    }

    @Override
    @Async("DataPushExecutor")
    @Transactional(rollbackFor = Throwable.class)
    public void pushBatch(String cacheKey, String cacheColumn, Long cacheSeconds, String pushUrls, String dataType, List<?> dataList) {
        List<JobDataPushLog> jobDataPushLogList = new ArrayList<>();
        String dataJson = JSONObject.toJSONString(dataList);
        if (StringUtils.isNotBlank(pushUrls)) {
            for (String pushUrl : pushUrls.split(Constants.DATA_PUSH_URL_MULTIPLE_SPLIT)) {
                JobDataPushLog log = new JobDataPushLog();
                log.setDataType(dataType);
                log.setJobData(dataJson);
                log.setPushUrl(pushUrl);
                try {
                    String respStr = HttpUtil.post(pushUrl, dataJson);
                    JSONObject respObj = JSONObject.parseObject(respStr);
                    if (respObj.getBoolean(RTN_CODE_FIELD)) {
                        log.setStatus(Constants.DATA_PUSH_STATUS_SUCCESS);
                        dataList.forEach(d -> {
                            Integer cacheVal = d.hashCode();
                            JSONObject j = JSONObject.parseObject(JSONObject.toJSONString(d));
                            redisUtil.set(cacheKey + j.getString(cacheColumn), cacheVal, cacheSeconds, TimeUnit.SECONDS);
                        });
                    } else {
                        log.setStatus(Constants.DATA_PUSH_STATUS_FAIL);
                        log.setRemark(respObj.getString(RTN_MSG_FIELD));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.setStatus(Constants.DATA_PUSH_STATUS_FAIL);
                    log.setRemark(e.getMessage());
                }
                jobDataPushLogList.add(log);
            }
        } else {
            JobDataPushLog log = new JobDataPushLog();
            log.setStatus(Constants.DATA_PUSH_STATUS_PENDING);
            log.setJobData(dataJson);
            log.setDataType(dataType);
            jobDataPushLogList.add(log);
        }
        this.saveBatch(jobDataPushLogList);
    }
}
